from abc import ABCMeta, abstractmethod
import yaml
from rocket.builder.ir import ConfigIR, Component


class AbstractResourceLoader(metaclass=ABCMeta):

    @abstractmethod
    def load(self, configfile: str) -> ConfigIR:
        pass

    def _build_component(self, component):

        if isinstance(component, dict) and "type" in component:
            type = component.get("type")
            kwargs = {}
            for key, val in component.items():
                if key != 'type':
                    kwargs[key] = self._build_component(val)

            return Component(type, **kwargs)
        elif isinstance(component, (tuple, list)):
            instances = []
            for item in component:
                instances.append(self._build_component(item))

            return instances
        else:
            return component


class YamlResourceLoader(AbstractResourceLoader):

    def load(self, configfile: str) -> ConfigIR:
        config = ConfigIR()
        with open(configfile, 'r') as fin:
            context = yaml.load_all(fin.read(), yaml.FullLoader)
            context = next(context)

            for key, value in context.items():
                setattr(config, key, self._build_component(value))

        return config


class JsonResourceLoader(AbstractResourceLoader):

    def load(self, configfile: str) -> ConfigIR:
        raise NotImplemented()


class PyResourceLoader(AbstractResourceLoader):

    def load(self, configfile: str) -> ConfigIR:
        raise NotImplemented()
